#include <string.h>
#include <stdio.h>
#include "air105.h"

void NVIC_Configuration(void);
void UART_Configuration(void);
void TIMER_Configuration(void);

int32_t TimerFlag = 0;
// coremark里定义了自己的main函数，此处的main函数执行系统初始化工作，在core_portme.c里的portable_init里调用即可
void main_original(void)
{
    SYSCTRL_ClocksTypeDef clocks;
    SYSCTRL_PLLConfig(SYSCTRL_PLL_204MHz); // 设置PLL时钟
    SYSCTRL_PLLDivConfig(SYSCTRL_PLL_Div_None);//设置PLL分频为不分频，即204MHz
    SYSCTRL_GetClocksFreq(&clocks); // 获取时钟频率

    SYSCTRL_APBPeriphClockCmd(SYSCTRL_APBPeriph_UART0 | SYSCTRL_APBPeriph_TIMM0 | SYSCTRL_APBPeriph_GPIO, ENABLE); // 使能UART0、TIMM0、GPIO时钟
    SYSCTRL_APBPeriphResetCmd(SYSCTRL_APBPeriph_UART0 | SYSCTRL_APBPeriph_TIMM0, ENABLE);                          // 复位UART0、TIMM0

    UART_Configuration();  // 配置UART0
    TIMER_Configuration(); // 配置TIMM0
    NVIC_Configuration();  // 配置中断
    printf("CPU_Frequency:%d,\nHCLK_Frequency:%d,\nPCLK_Frequency:%d,\nPLL_Frequency:%d\n\r", clocks.CPU_Frequency / 1000000, clocks.HCLK_Frequency / 1000000, clocks.PCLK_Frequency / 1000000, clocks.PLL_Frequency / 1000000);
    printf("LuatOS AIR105 COREMARK Demo V1.0.\n");
}

void TIMER_Configuration(void)
{
    TIM_InitTypeDef TIM_InitStruct;
    TIM_InitStruct.TIM_Period = (SYSCTRL->PCLK_1MS_VAL); // 1*1000ms

    TIM_InitStruct.TIMx = TIM_0;
    TIM_Init(TIMM0, &TIM_InitStruct);
    TIM_ITConfig(TIMM0, TIM_InitStruct.TIMx, ENABLE); // 使能TIMM0的TIM_0中断
}

void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_SetPriorityGrouping(NVIC_PriorityGroup_3); // 设置中断优先级分组

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // 使能TIM0_0中断
    NVIC_InitStructure.NVIC_IRQChannel = TIM0_0_IRQn;         // TIM0_0中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7; // 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        // 子优先级
    NVIC_Init(&NVIC_InitStructure);
}

void UART_Configuration(void)
{
    UART_InitTypeDef UART_InitStructure;

    GPIO_PinRemapConfig(GPIOA, GPIO_Pin_0 | GPIO_Pin_1, GPIO_Remap_0);

    UART_InitStructure.UART_BaudRate = 115200;
    UART_InitStructure.UART_WordLength = UART_WordLength_8b;
    UART_InitStructure.UART_StopBits = UART_StopBits_1;
    UART_InitStructure.UART_Parity = UART_Parity_No;

    UART_Init(UART0, &UART_InitStructure);
}

int SER_PutChar(int ch)
{
    while (!UART_IsTXEmpty(UART0))
        ;
    UART_SendData(UART0, (uint8_t)ch);

    return ch;
}

int fputc(int c, FILE *f)
{
    /* Place your implementation of fputc here */
    /* e.g. write a character to the USART */
    if (c == '\n')
    {
        SER_PutChar('\r');
    }
    return (SER_PutChar(c));
}

#ifdef USE_FULL_ASSERT

/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    printf("Wrong parameters value: file %s on line %d\r\n", file, line);
    /* Infinite loop */
    while (1)
    {
    }
}
#endif
